import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:tx_live_plugin/widget/tx_live_chat.dart';
import 'package:tx_live_plugin_example/http/http_client.dart';
import 'package:tx_live_plugin_example/http/url_path.dart';
import 'package:tx_live_plugin_example/util/click.dart';
import 'package:tx_live_plugin_example/util/logic_presenter.dart';
import 'package:tx_live_plugin_example/util/toast_utils.dart';
import 'package:tx_live_plugin_example/util/widget_utils.dart';

///视频聊天
///meetType 咨询类型，则需要传orderNo、productNo； 接谈类型：
class ChatPage extends StatefulWidget {
  final String interviewId;
  final String? orderNo;
  final String? productNo;
  final int meetType;

  const ChatPage({Key? key, required this.interviewId,
    this.orderNo,
    this.productNo,
    this.meetType = MEETING_TYPE_CONSULT}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _ChatPageState();
}

class _ChatPageState extends State<ChatPage> {
  late _ChatModel _model;

  @override
  void initState() {
    super.initState();
    _model = _ChatModel(
      disposePage: _disposePage,
      showDialogBack: _showDialogBack,
    );
    _model.addListener(() {
      if (mounted) setState(() {});
    });
    Future.delayed(const Duration(milliseconds: 100),()=>{
              _model.startChartInfo(
                  interviewId: widget.interviewId,
                  orderNo: widget.orderNo,
                  productNo: widget.productNo,
                  meetType: widget.meetType)
            });
  }

  _showDialogBack(String msg) async {
    await WidgetUtils.showSingleDialog(context, msg);
  }

  void _disposePage() {
    if(mounted) {
      Navigator.pop(context,_model._chatResult);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: InkWell(
            onTap: () => Navigator.pop(context),
            child: const Icon(Icons.arrow_back_ios_rounded, size: 18)),
        // actions: _actionsWidget(),
      ),
      body: SizedBox(
        width: double.infinity,
        height: double.infinity,
        child: Stack(
          children: [
            Positioned.fill(child: Container(color: Colors.redAccent)),
            Positioned.fill(child: TxLiveChat(controller: _model.controller, callback: _model)),
            Align(alignment: Alignment.bottomCenter, child: _bottomBtn()),
            Align(
                alignment: Alignment.topCenter,
                child: Visibility(
                    visible: _model.isLoading,
                    child: const SizedBox(
                      width: 30,
                      height: 30,
                      child: CupertinoActivityIndicator(),
                    ))),
            Align(alignment: Alignment.topRight, child: _timeWidget()),
          ],
        ),
      ),
    );
  }

  Widget _bottomBtn() {
    if (!_model.isChatting) return Container();
    return SizedBox(
      height: 55,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          _singleBtn(
              _model.isRecording
                  ? Icons.multitrack_audio_rounded
                  : Icons.video_call_rounded,
              _model.videoRecord,
              bgColor: _model.isRecording ? Colors.blueAccent : Colors.black54),
          const SizedBox(width: 15),
          _singleBtn(
              _model.isOpenAudio
                  ? Icons.keyboard_voice_rounded
                  : Icons.music_off_rounded,
              _model.switchSound),
          const SizedBox(width: 15),
          _singleBtn(Icons.call, _model.stopChat, bgColor: Colors.redAccent),
        ],
      ),
    );
  }

  Widget _singleBtn(IconData icon, Function onTap,
      {Color bgColor = Colors.black54}) {
    return Click(
      onTap: onTap,
      child: SizedBox(
        width: 55,
        height: 55,
        child: Padding(
          padding: const EdgeInsets.all(10),
          child: ClipOval(
            //borderRadius: const BorderRadius.all(Radius.circular(15)),
            child: Container(
              color: bgColor,
              child: Icon(icon, color: Colors.white, size: 25),
            ),
          ),
        ),
      ),
    );
  }

  Widget _timeWidget() {
    return Padding(
        padding: const EdgeInsets.fromLTRB(15, 12, 15, 12),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(15),
          child: Container(
            width: 80,
            height: 30,
            color: Colors.black54,
            alignment: Alignment.center,
            child: Text(_model.currentTimeStr),
          ),
        ));
  }
}

///逻辑处理
class _ChatModel with ChangeNotifier, ChatCallback {
  final ChatController controller = ChatController();
  final VoidCallback? disposePage;
  final Function(String msg)? showDialogBack;
  bool isChatting = false;
  bool isLoading = false;
  bool isRecording = false;
  bool isOpenAudio = true;
  Timer? _timer;

  //10分钟，单位秒
  static const int _maxTime = 10 * 60;
  static const int _minTime = 0;
  int _currentTime = _minTime;
  String currentTimeStr = '';
  //会议数据
  String? _interviewId;
  String? _roomMemberId;//当前用户，在视频会议中的成员id
  String? _chatResult = '';

  _ChatModel({this.disposePage, this.showDialogBack});

  ///录制 true表示录制开启，false开启失败重试，null可以继续请求开启
  Future<bool?> videoRecord() async{
    if(_roomMemberId == null) return false;
    var data = await HttpClient.post(UrlPath.START_RECORD_MEETING,params: {
    "roomNum":_roomMemberId,
    },onValue: (res){
      if(res['success'] == true){
        notifyListeners();
        isRecording = true;
        ToastUtils.showToast("视频开始录制");
        return true;
      }
      if(res["retry"] == true){
        videoRecord();
        return false;
      }
    });

    return data;
  }

  ///切换 静音
  switchSound() async{
    await controller.switchAudio();
    isOpenAudio = !isOpenAudio;
    notifyListeners();
    var audio = await controller.isOpenAudio();
    print("-------------------视频会议，当前用户是否静音 $audio, isOpenAudio $isOpenAudio");
  }

  ///停止视频，退出房间
  stopChat() {
    if(_roomMemberId == null){
      print("------------------stopChat : _roomMemberId is null");
      controller.stopChat();
      disposePage?.call();
      return;
    }
    HttpClient.post(UrlPath.CLOSE_ROOM,params: {
      "roomNum":_roomMemberId,
      "appointmentInterviewId":_interviewId,
    },onValue: (res){
      if(res['success'] == true){
        var list = res['members'];
        if(list is List){
          //OpinionActivity.start(getActivity(), mInterviewId,mOrderNoId, meetingType == 1, list);
          print("-------------------------视频聊天会议，进行设置视频意见，$res");
        }
        controller.stopChat();
        disposePage?.call();
        return;
      }
      if(res['retry'] == true){
        stopChat();
        return;
      }
      ToastUtils.showToast("解散失败。。");
      controller.stopChat();
      disposePage?.call();
      print("------------------stopChat finish : _roomMemberId $_roomMemberId");
    });
  }

  startChartInfo({
    required String interviewId,
    String? orderNo,
    String? productNo,
    int meetType = MEETING_TYPE_CONSULT,
  }) async {
    isLoading = true;
    _interviewId = interviewId;
    notifyListeners();
    var consult = meetType == MEETING_TYPE_CONSULT;
    Map<String,dynamic> pa = {
      "appointmentInterviewId":interviewId,
    };
    if(consult){
      pa['orderNo'] = orderNo;
      pa['productNo'] = productNo;
      pa['meetingType'] = meetType;
    }
    print("-----------startChartInfo");
    await HttpClient.post(
        consult ? UrlPath.CREATE_CONSULT_ROOM : UrlPath.CREATE_INTERVIEW_ROOM,
        params: pa,
        onValue: (res)async{
          if(res['success'] != true){
            _chatResult = "视频会议房间创建失败";
            ToastUtils.showToast("视频会议房间创建失败");
            disposePage?.call();
            print("-----------startChartInfo fail 视频会议房间创建失败");
            return;
          }
          _roomMemberId = "${res['roomMemberId']}";
          await controller.startChat(
            sdkAppId: LogicPresenter.parseInt(res['sdkAppId']),
            userSign: "${res['userSign']}",
            roomId: LogicPresenter.parseInt(res['roomNum']),
            userId: LogicPresenter.user?.notaryId,
          );
          print("-----------controller.startChat finish");
        },
    );
    isLoading = false;
    notifyListeners();
  }

  _startTimer(int maxTime,VoidCallback complete) {
    print("-----------_startTimer");
    _timer?.cancel();
    _currentTime = _minTime;
    _timer = Timer.periodic(const Duration(seconds: 1), (t) {
      _currentTime++;
      if (_currentTime == maxTime) {
        _timer?.cancel();
        _timer = null;
        complete.call();
        return;
      }
      var minute = LogicPresenter.twoDigits(_currentTime ~/ 60);
      var second = LogicPresenter.twoDigits(_currentTime % 60);
      currentTimeStr = "$minute:$second";
      notifyListeners();
    });
  }

  _cancelTimer(){
    _timer?.cancel();
    _timer = null;
  }

  @override
  void dispose() {
    print("-----------dispose");
    _cancelTimer();
    controller.dispose();
    super.dispose();
  }

  ///一些通知
  @override
  toast(String? message) {
    print("-----------toast : message $message");
    ToastUtils.showToast(message ?? '');
  }

  ///视频会议："进入房间失败"、"创建者已结束会议"，需要关闭页面
  @override
  fail(String? message) {
    print("-----------fail : message $message");
    ToastUtils.showToast(message ?? '');
    _chatResult = message;
    disposePage?.call();
  }

  ///通知视频房间会议 创建成功，可以直接toast提示
  @override
  notifyRoomCreate(String? toast) {
    print("-----------notifyRoomCreate : toast $toast");
    if(isChatting) return;//防止重复通知
    _curStart();
    ToastUtils.showToast(toast ?? '');
    HttpClient.post(UrlPath.JOIN_INTERVIEW_ROOM,params: {
      "roomMemberId":_roomMemberId,
    });
  }

  _curStart(){
    isChatting = true;
    _startTimer(_maxTime, () {
      ToastUtils.showToast("视频达到最大时间，退出视频房间");
      controller.stopChat();
      disposePage?.call();
    });
    notifyListeners();
  }
  ///开始计时器，
  ///intoRoom是否进入房间，false代表尝试进入房间，可以计时1分钟后提示进入房间失败，关闭页面，如果收到true则停止该计时；
  ///true代表成功进入房间，计时30分钟后，退出房间
  @override
  startTime(bool? intoRoom, int? secondTime) {
    print("-----------startTime : intoRoom $intoRoom, secondTime $secondTime");
    if(intoRoom == true){
      _curStart();
    }else{
      _startTimer(secondTime??60, () {
        ToastUtils.showToast("进入房间失败，退出");
        controller.stopChat();
        disposePage?.call();
      });
    }
  }
}
